package com.lmaos.basetools.base;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.util.Arrays;
/** 位运算工具
 * 
 */
public class SBitUtils {
	private final static byte[] emptyBytes = {};
	public static byte[] toBytesByShortB(short val){
		byte[] bs = new byte[2];
		bs[0] = (byte) ((val>>8)&0xFF);
		bs[1] = (byte) ((val)&0xFF);
		return bs;
	}
	public static short toShortByBytesB(byte[] bs){
		short val = (short) (((bs[0]&0xFF)<<8)|(bs[1]&0xFF));
		return val;
	}
	public static byte[] toBytesByShortL(short val){
		byte[] bs = new byte[2];
		bs[1] = (byte) ((val>>8)&0xFF);
		bs[0] = (byte) ((val)&0xFF);
		return bs;
	}
	public static short toShortByBytesL(byte[] bs){
		short val = (short) (((bs[1]&0xFF)<<8)|(bs[0]&0xFF));
		return val;
	}
	
	// int 
	public static byte[] toBytesByIntB(int val){
		byte[] bs = new byte[4];
		bs[0] = (byte) ((val>>24)&0xFF);
		bs[1] = (byte) ((val>>16)&0xFF);
		bs[2] = (byte) ((val>>8)&0xFF);
		bs[3] = (byte) ((val)&0xFF);
		return bs;
	}
	public static int toIntByBytesB(byte[] bs){
		int val = (int) (((bs[0]&0xFF)<<24)
				|((bs[1]&0xFF)<<16)
				|((bs[2]&0xFF)<<8)
				|(bs[3]&0xFF));
		return val;
	}
	
	public static byte[] toBytesByIntL(int val){
		byte[] bs = new byte[4];
		bs[3] = (byte) ((val>>24)&0xFF);
		bs[2] = (byte) ((val>>16)&0xFF);
		bs[1] = (byte) ((val>>8)&0xFF);
		bs[0] = (byte) ((val)&0xFF);
		return bs;
	}
	public static int toIntByBytesL(byte[] bs){
		int val = (int) (((bs[3]&0xFF)<<24)
				|((bs[2]&0xFF)<<16)
				|((bs[1]&0xFF)<<8)
				|(bs[0]&0xFF));
		return val;
	}
	
	// long
	public static byte[] toBytesByLongB(long val){
		byte[] bs = new byte[8];
		bs[0] = (byte) ((val>>56)&0xFF);
		bs[1] = (byte) ((val>>48)&0xFF);
		bs[2] = (byte) ((val>>40)&0xFF);
		bs[3] = (byte) ((val>>32)&0xFF);
		bs[4] = (byte) ((val>>24)&0xFF);
		bs[5] = (byte) ((val>>16)&0xFF);
		bs[6] = (byte) ((val>>8)&0xFF);
		bs[7] = (byte) ((val)&0xFF);
		return bs;
	}
	public static long toLongByBytesB(byte[] bs){
		long val = (long) (
				 ((long)(bs[0]&0xFF)<<56)
				|((long)(bs[1]&0xFF)<<48)
				|((long)(bs[2]&0xFF)<<40)
				|((long)(bs[3]&0xFF)<<32)
				|((long)(bs[4]&0xFF)<<24)
				|((long)(bs[5]&0xFF)<<16)
				|((long)(bs[6]&0xFF)<<8)
				|(long)(bs[7]&0xFF));
		return val;
	}
	
	public static byte[] toBytesByLongL(long val){
		byte[] bs = new byte[8];
		bs[7] = (byte) ((val>>56)&0xFF);
		bs[6] = (byte) ((val>>48)&0xFF);
		bs[5] = (byte) ((val>>40)&0xFF);
		bs[4] = (byte) ((val>>32)&0xFF);
		bs[3] = (byte) ((val>>24)&0xFF);
		bs[2] = (byte) ((val>>16)&0xFF);
		bs[1] = (byte) ((val>>8)&0xFF);
		bs[0] = (byte) ((val)&0xFF);
		return bs;
	}
	public static long toLongByBytesL(byte[] bs){
		long val = (long) (
				 ((long)(bs[7]&0xFF)<<56)
				|((long)(bs[6]&0xFF)<<48)
				|((long)(bs[5]&0xFF)<<40)
				|((long)(bs[4]&0xFF)<<32)
				|((long)(bs[3]&0xFF)<<24)
				|((long)(bs[2]&0xFF)<<16)
				|((long)(bs[1]&0xFF)<<8)
				|(long)(bs[0]&0xFF));
		return val;
	}
	
	// double
	public static byte[] toBytesByDoubleB(double val){
		
		return toBytesByLongB(Double.doubleToLongBits(val));
	}
	public static double toDoubleByBytesB(byte[] bs){
		long val = toLongByBytesB(bs);
		return Double.longBitsToDouble(val);
	}
	public static byte[] toBytesByDoubleL(double val){
		
		return toBytesByLongL(Double.doubleToLongBits(val));
	}
	public static double toDoubleByBytesL(byte[] bs){
		long val = toLongByBytesL(bs);
		return Double.longBitsToDouble(val);
	}
	
	// float
	public static byte[] toBytesByFloatB(float val){
		
		return toBytesByIntB(Float.floatToIntBits(val));
	}
	public static float toFloatByBytesB(byte[] bs){
		int val = toIntByBytesB(bs);
		return Float.intBitsToFloat(val);
	}
	public static byte[] toBytesByFloatL(float val){
		
		return toBytesByIntB(Float.floatToIntBits(val));
	}
	public static float toFloatByBytesL(byte[] bs){
		int val = toIntByBytesB(bs);
		return Float.intBitsToFloat(val);
	}
	public static byte[] toBytesByCharB(char c){
		return toBytesByShortB((short) c);
	}
	public static char toCharByBytesB(byte[] bs){
		return (char) toShortByBytesB(bs);
	}
	public static char toCharByBytesL(byte[] bs){
		return (char) toShortByBytesL(bs);
	}
	public static byte[] toBytesByCharL(char c){
		return toBytesByShortL((short) c);
	}
	
	public static byte toByteByBoolean(boolean bool){
		return (byte) (bool?1:0);
	}
	public static boolean toBooleanByByte(byte val){
		return val == 1;
	}
	public static byte[] toBytesByPrimitive(Object val,boolean littleEnd){
		return toBytesByPrimitive(val, littleEnd, null);
	}
	public static byte[] toBytesByPrimitive(Object val,boolean littleEnd,String charsetName){
		if(val == null){
			return emptyBytes;
		}
		Class type = val.getClass();
		byte[] result = null;
		if(isInt(type)){
			int v = getNumber(val, 0).intValue();
			result =  toBytesByInt(v, littleEnd); //littleEnd?toBytesByIntL(v):toBytesByIntB(v);
		}else if(isLong(type)){
			long v = getNumber(val, 0).longValue();
			result =  toBytesByLong(v, littleEnd);//littleEnd?toBytesByLongL(v):toBytesByLongB(v);
		}else if(isShort(type)){
			short v = getNumber(val, 0).shortValue();
			result =  toBytesByShort(v, littleEnd);//littleEnd?toBytesByShortL(v):toBytesByShortB(v);
		}else if(isByte(type)){
			byte v = getNumber(val, 0).byteValue();
			result =  new byte[]{v};
		}else if(isFloat(type)){
			float v = getNumber(val, 0).floatValue();
			result =  toBytesByFloat(v, littleEnd);//littleEnd?toBytesByFloatL(v):toBytesByFloatB(v);
		}else if(isDouble(type)){
			double v = getNumber(val, 0).doubleValue();
			result =  toBytesByDouble(v, littleEnd);//littleEnd?toBytesByDoubleL(v):toBytesByDoubleB(v);
		}else if(isChar(type)){
			char v = (Character)val;
			result =  toBytesByChar(v, littleEnd);//littleEnd?toBytesByCharL(v):toBytesByCharB(v);
		}else if(isBoolean(type)){
			result =  new byte[]{toByteByBoolean((Boolean)val)};
		}else if(type == Integer[].class){
			Integer[] v = (Integer[]) val;
			result =  toBytesByInts(v, littleEnd);
		}else if(type == int[].class){
			int[] v = (int[]) val;
			result =  toBytesByInts(v, littleEnd);
		}else if(type == Long[].class){
			Long[] v = (Long[]) val;
			result =  toBytesByLongs(v, littleEnd);
		}else if(type == long[].class){
			long[] v = (long[]) val;
			result =  toBytesByLongs(v, littleEnd);
		}else if(type == Short[].class){
			Short[] v = (Short[]) val;
			result =  toBytesByShorts(v, littleEnd);
		}else if(type == short[].class){
			short[] v = (short[]) val;
			result =  toBytesByShorts(v, littleEnd);
		}else if(type == char[].class){
			char[] v = (char[]) val;
			result =  toBytesByChars(v, littleEnd);
		}else if(type == Character[].class){
			Character[] v = (Character[]) val;
			result =  toBytesByCharacters(v, littleEnd);
		}else if(type == float[].class){
			float[] v = (float[])val;
			result =  toBytesByFloats(v, littleEnd);
		}else if(type == Float[].class){
			Float[] v = (Float[])val;
			result =  toBytesByFloats(v, littleEnd);
		}else if(type == double[].class){
			double[] v = (double[])val;
			result =  toBytesByDoubles(v, littleEnd);
		}else if(type == Double[].class){
			Double[] v = (Double[])val;
			result =  toBytesByDoubles(v, littleEnd);
		}else if(type == byte[].class){
			result = (byte[])val;
		}else if(type == Byte[].class){
			result = toBytes((Byte[])val);
		}
		else if(type==String.class||type==StringBuffer.class||type==StringBuilder.class||type==BigDecimal.class){
			if(charsetName == null||charsetName.isEmpty()){
				result =  toBytesByStringBit2(val.toString(), littleEnd);
			}else{
				result =  toBytesByStringBit1(val.toString(), charsetName);
			}
		}else{
			
		}
		return result;
	}
	
	
	public static <T>T toPrimitiveByBytes(byte[] bs,Class<T> type,boolean littleEnd){
		return toPrimitiveByBytes(bs, type, littleEnd, null);
	}
	public static <T>T toPrimitiveByBytes(byte[] bs,Class<T> type,boolean littleEnd,String charsetName){
		if(bs == null||bs.length == 0){
			return null;
		}
		Object result = null;
		if(isInt(type)){
			result =  toIntByBytes(bs, littleEnd);
		}else if(isLong(type)){
			result =  toLongByBytes(bs, littleEnd);
		}else if(isShort(type)){
			result =  toShortByBytes(bs, littleEnd);
		}else if(isByte(type)){
			result =  bs[0];
		}else if(isFloat(type)){
			result =  toFloatByBytes(bs, littleEnd);
		}else if(isDouble(type)){
			result =  toDoubleByBytes(bs, littleEnd);
		}else if(isChar(type)){
			result =  toCharByBytes(bs, littleEnd);
		}else if(isBoolean(type)){
			result = toBooleanByByte(bs[0]);
		}else if(type == Integer[].class){
			result = toIntgersByBytes(bs, littleEnd);
		}else if(type == int[].class){
			result = toIntsByBytes(bs, littleEnd);
		}else if(type == Long[].class){
			result =  toLongersByBytes(bs, littleEnd);
		}else if(type == long[].class){
			result =  toLongsByBytes(bs, littleEnd);
		}else if(type == Short[].class){
			result =  toShortersByBytes(bs, littleEnd);
		}else if(type == short[].class){
			result =  toShortsByBytes(bs, littleEnd);
		}else if(type == char[].class){
			result = toCharsByBytes(bs, littleEnd);
		}else if(type == Character[].class){
			result = toCharactersByBytes(bs, littleEnd);
		}else if(type == float[].class){
			result = toFloatsByBytes(bs, littleEnd);
		}else if(type == Float[].class){
			result = toFloatersByBytes(bs, littleEnd);
		}else if(type == double[].class){
			result = toDoublesByBytes(bs, littleEnd);
		}else if(type == Double[].class){
			result = toDoublersByBytes(bs, littleEnd);
		}else if(type == Byte[].class){
			result = toByters(bs);
		}else if(type == byte[].class){
			result = bs;
		}
		else if(type==String.class||type==StringBuffer.class||type==StringBuilder.class||type==BigDecimal.class){
			if(charsetName == null||charsetName.isEmpty()){
				result =  toStringByBytesBit2(bs, littleEnd).trim();
			}else{
				result =  toStringByBytesBit1(bs, charsetName).trim();
			}
			if(type==StringBuffer.class){
				result = new StringBuffer(result.toString());
			}else if(type == StringBuilder.class){
				result = new StringBuilder(result.toString());
			}else if(type==BigDecimal.class){
				result = new BigDecimal(result.toString());
			}
		}else{
			
		}
		return (T)result;
	}
	
	
	public static byte[] toBytesByInt(int val,boolean littleEnd){
		return littleEnd?toBytesByIntL(val):toBytesByIntB(val);
	}
	public static byte[] toBytesByLong(long val,boolean littleEnd){
		return littleEnd?toBytesByLongL(val):toBytesByLongB(val);
	}
	public static byte[] toBytesByShort(short val,boolean littleEnd){
		return littleEnd?toBytesByShortL(val):toBytesByShortB(val);
	}
	public static byte[] toBytesByFloat(float val,boolean littleEnd){
		return littleEnd?toBytesByFloatL(val):toBytesByFloatB(val);
	}
	public static byte[] toBytesByDouble(double val,boolean littleEnd){
		return littleEnd?toBytesByDoubleL(val):toBytesByDoubleB(val);
	}
	public static byte[] toBytesByChar(char val,boolean littleEnd){
		return littleEnd?toBytesByCharL(val):toBytesByCharB(val);
	}
	
	
	public static int toIntByBytes(byte[] bs,boolean littleEnd){
		return littleEnd?toIntByBytesL(bs):toIntByBytesB(bs);
	}
	public static long toLongByBytes(byte[] bs,boolean littleEnd){
		return littleEnd?toLongByBytesL(bs):toLongByBytesB(bs);
	}
	public static float toFloatByBytes(byte[] bs,boolean littleEnd){
		return littleEnd?toFloatByBytesL(bs):toFloatByBytesB(bs);
	}
	public static short toShortByBytes(byte[] bs,boolean littleEnd){
		return littleEnd?toShortByBytesL(bs):toShortByBytesB(bs);
	}
	public static double toDoubleByBytes(byte[] bs,boolean littleEnd){
		return littleEnd?toDoubleByBytesL(bs):toDoubleByBytesB(bs);
	}
	public static char toCharByBytes(byte[] bs,boolean littleEnd){
		return littleEnd?toCharByBytesL(bs):toCharByBytesB(bs);
	}
	
	
	public static byte[] toBytesByChars(char[] cs,boolean littleEnd){
		byte[] bs = new byte[cs.length*2];
		for (int i = 0; i < cs.length; i++) {
			byte[] bit = toBytesByChar(cs[i], littleEnd);
			System.arraycopy(bit, 0, bs, i*2, 2);
		}
		return bs;
	}
	public static char[] toCharsByBytes(byte[] bs,boolean littleEnd){
		char[] cs = new char[bs.length];
		for (int i = 0; i < bs.length; i+=2) {
			byte[] bit = {bs[i],bs[i+1]};
			cs[i/2] = toCharByBytes(bit, littleEnd);
		}
		return cs;
	}
	public static byte[] toBytesByCharacters(Character[] cs,boolean littleEnd){
		byte[] bs = new byte[cs.length*2];
		for (int i = 0; i < cs.length; i++) {
			char v = cs[i]==null?(char)0:cs[i];
			byte[] bit = toBytesByChar(v, littleEnd);
			System.arraycopy(bit, 0, bs, i*2, 2);
		}
		return bs;
	}
	public static Character[] toCharactersByBytes(byte[] bs,boolean littleEnd){
		Character[] cs = new Character[bs.length];
		for (int i = 0; i < bs.length; i+=2) {
			byte[] bit = {bs[i],bs[i+1]};
			cs[i/2] = toCharByBytes(bit, littleEnd);
		}
		return cs;
	}
	public static byte[] toBytesByInts(int[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*4];
		for (int i = 0; i < val.length; i++) {
			byte[] bit = toBytesByInt(val[i], littleEnd);
			System.arraycopy(bit, 0, bs, i*4, bit.length);
		}
		return bs;
	}
	public static byte[] toBytesByInts(Integer[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*4];
		for (int i = 0; i < val.length; i++) {
			int v = getNumber(val[i], 0).intValue();
			byte[] bit = toBytesByInt(v, littleEnd);
			System.arraycopy(bit, 0, bs, i*4, bit.length);
		}
		return bs;
	}
	public static int[] toIntsByBytes(byte[] bs,boolean littleEnd){
		int[] val = new int[bs.length/4];
		for (int i = 0; i < bs.length; i+=4) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3]};
			val[i/4] = toIntByBytes(bit, littleEnd);
		}
		return val;
	}
	public static Integer[] toIntgersByBytes(byte[] bs,boolean littleEnd){
		Integer[] val = new Integer[bs.length/4];
		for (int i = 0; i < bs.length; i+=4) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3]};
			val[i/4] = toIntByBytes(bit, littleEnd);
		}
		return val;
	}
	public static byte[] toBytesByFloats(float[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*4];
		for (int i = 0; i < val.length; i++) {
			byte[] bit = toBytesByFloat(val[i], littleEnd);
			System.arraycopy(bit, 0, bs, i*4, bit.length);
		}
		return bs;
	}
	public static byte[] toBytesByFloats(Float[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*4];
		for (int i = 0; i < val.length; i++) {
			float v = getNumber(val[i], 0).floatValue();
			byte[] bit = toBytesByFloat(v, littleEnd);
			System.arraycopy(bit, 0, bs, i*4, bit.length);
		}
		return bs;
	}
	public static float[] toFloatsByBytes(byte[] bs,boolean littleEnd){
		float[] val = new float[bs.length/4];
		for (int i = 0; i < bs.length; i+=4) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3]};
			val[i/4] = toFloatByBytes(bit, littleEnd);
		}
		return val;
	}
	public static Float[] toFloatersByBytes(byte[] bs,boolean littleEnd){
		Float[] val = new Float[bs.length/4];
		for (int i = 0; i < bs.length; i+=4) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3]};
			val[i/4] = toFloatByBytes(bit, littleEnd);
		}
		return val;
	}
	public static byte[] toBytesByLongs(long[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*8];
		for (int i = 0; i < val.length; i++) {
			byte[] bit = toBytesByLong(val[i], littleEnd);
			System.arraycopy(bit, 0, bs, i*8, bit.length);
		}
		return bs;
	}
	public static byte[] toBytesByLongs(Long[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*8];
		for (int i = 0; i < val.length; i++) {
			long v = getNumber(val[i], 0).longValue();
			byte[] bit = toBytesByLong(v, littleEnd);
			System.arraycopy(bit, 0, bs, i*8, bit.length);
		}
		return bs;
	}
	public static long[] toLongsByBytes(byte[] bs,boolean littleEnd){
		long[] val = new long[bs.length/8];
		for (int i = 0; i < bs.length; i+=8) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3],bs[i+4],bs[i+5],bs[i+6],bs[i+7]};
			val[i/8] = toLongByBytes(bit, littleEnd);
		}
		return val;
	}
	public static Long[] toLongersByBytes(byte[] bs,boolean littleEnd){
		Long[] val = new Long[bs.length/8];
		for (int i = 0; i < bs.length; i+=8) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3],bs[i+4],bs[i+5],bs[i+6],bs[i+7]};
			val[i/8] = toLongByBytes(bit, littleEnd);
		}
		return val;
	}
	public static byte[] toBytesByDoubles(double[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*8];
		for (int i = 0; i < val.length; i++) {
			byte[] bit = toBytesByDouble(val[i], littleEnd);
			System.arraycopy(bit, 0, bs, i*8, bit.length);
		}
		return bs;
	}
	public static byte[] toBytesByDoubles(Double[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*8];
		for (int i = 0; i < val.length; i++) {
			double v = getNumber(val[i], 0).doubleValue();
			byte[] bit = toBytesByDouble(v, littleEnd);
			System.arraycopy(bit, 0, bs, i*8, bit.length);
		}
		return bs;
	}
	public static double[] toDoublesByBytes(byte[] bs,boolean littleEnd){
		double[] val = new double[bs.length/8];
		for (int i = 0; i < bs.length; i+=8) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3],bs[i+4],bs[i+5],bs[i+6],bs[i+7]};
			val[i/8] = toDoubleByBytes(bit, littleEnd);
		}
		return val;
	}
	public static Double[] toDoublersByBytes(byte[] bs,boolean littleEnd){
		Double[] val = new Double[bs.length/8];
		for (int i = 0; i < bs.length; i+=8) {
			byte[] bit = {bs[i],bs[i+1],bs[i+2],bs[i+3],bs[i+4],bs[i+5],bs[i+6],bs[i+7]};
			val[i/8] = toDoubleByBytes(bit, littleEnd);
		}
		return val;
	}
	
	
	public static byte[] toBytesByShorts(short[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*2];
		for (int i = 0; i < val.length; i++) {
			byte[] bit = toBytesByShort(val[i], littleEnd);
			System.arraycopy(bit, 0, bs, i*2, bit.length);
		}
		return bs;
	}
	public static byte[] toBytesByShorts(Short[] val,boolean littleEnd){
		byte[] bs = new byte[val.length*2];
		for (int i = 0; i < val.length; i++) {
			short v = getNumber(val[i], 0).shortValue();
			byte[] bit = toBytesByShort(v, littleEnd);
			System.arraycopy(bit, 0, bs, i*2, bit.length);
		}
		return bs;
	}
	
	public static short[] toShortsByBytes(byte[] bs,boolean littleEnd){
		short[] val = new short[bs.length/2];
		for (int i = 0; i < bs.length; i+=2) {
			byte[] bit = {bs[i],bs[i+1]};
			val[i/2] = toShortByBytes(bit, littleEnd);
		}
		return val;
	}
	public static Short[] toShortersByBytes(byte[] bs,boolean littleEnd){
		Short[] val = new Short[bs.length/2];
		for (int i = 0; i < bs.length; i+=2) {
			byte[] bit = {bs[i],bs[i+1]};
			val[i/2] = toShortByBytes(bit, littleEnd);
		}
		return val;
	}
	
	public static byte[] toBytesByStringBit2(String str,boolean littleEnd){
		if(str == null){
			return emptyBytes;
		}
		return toBytesByChars(str.toCharArray(), littleEnd);
	}
	public static byte[] toBytesByStringBit1(String str,String charsetName){
		if(str == null){
			return emptyBytes; 
		}
		return str.getBytes(Charset.forName(charsetName));
	}
	
	public static String toStringByBytesBit2(byte[] bs,boolean littleEnd){
		return new String(toCharsByBytes(bs, littleEnd));
	}
	public static String toStringByBytesBit1(byte[] bs,String charsetName){
		return new String(bs,Charset.forName(charsetName));
	}
	public static int primitiveTypeSizeOf(Object obj){
		if(obj == null){
			return 0;
		}
		Class type = obj.getClass();
		if(type.isArray()){
			return primitiveTypeSizeOf(type.getComponentType())*Array.getLength(obj);
		}else if(type == String.class){
			return obj.toString().length()*2;
		}else{
			return primitiveTypeSizeOf(type);
		}
	}
	public static int primitiveTypeSizeOf(Class type){
		if(isInt(type)){
			return 4;
		}else if(isLong(type)){
			return 8;
		}else if(isShort(type)){
			return 2;
		}else if(isByte(type)){
			return 1;
		}else if(isFloat(type)){
			return 4;
		}else if(isDouble(type)){
			return 8;
		}else if(isChar(type)){
			return 2;
		}else if(type == String.class){
			return 2;
		}else if(isBoolean(type)){
			return 1;
		}else{
			return 0;
		}
	}
	
	public static long toLong(Object val,long def){
		if(val == null){
			return def;
		}
		if(val instanceof Number){
			return ((Number)val).longValue();
		}
		String sval = val.toString();
		if(sval.isEmpty()){
			return def;
		}
		try {
			return Long.parseLong(sval);
		} catch (Exception e) {
			return 0;
		}
	}
	
	public static Number getNumber(Object val,Number def){
		if(val == null){
			return def;
		}
		if(val instanceof Number){
			return (Number)val;
		}
		try{
			return new BigDecimal(String.valueOf(val));
		}catch(Exception e){
			return def;
		}
	}
	
	public static byte[] toBytesAndCut(byte[] bs,int maxLength,boolean leftAppend){
		return toBytes(bs, maxLength, leftAppend, true);
	}
	public static byte[] toBytes(byte[] bs,int maxLength,boolean leftAppend){
		return toBytes(bs, maxLength, leftAppend, false);
	}
	/**
	 * 说明：		<br>
	 * 时间：2017年8月17日 上午12:30:42
	 *
	 * @param bs
	 * @param maxLength	生成最大长度
	 * @param leftData	
	 * @param cut		超出最大长度是否剪切，如果为false则会发生异常
	 * @return
	 */
	public static byte[] toBytes(byte[] bs,int maxLength,boolean leftData,boolean cut){
		if(bs == null){
			return new byte[maxLength];
		}
		
		int length = bs.length;	// 原数据长度
		if(length == maxLength){// 
			return bs;
		}
		if(length>maxLength){
			if(cut){
				length = maxLength;
			}else{
				throw new IndexOutOfBoundsException("传入数组超过最大长度,传入长度:"+length+"，最大长度:"+maxLength);
			}
		}
		byte[] result = new byte[maxLength];
		if(leftData){
			System.arraycopy(bs, 0, result, 0, length);
		}else{
			System.arraycopy(bs, 0, result, maxLength-length, length);
		}
		return result;
	}
	
	public static byte[] toBytes(Byte[] bs){
		byte[] bs2 = new byte[bs.length];
		for (int i = 0; i < bs2.length; i++) {
			bs2[i] = bs[i];
		}
		return bs2;
	}
	public static Byte[] toByters(byte[] bs){
		Byte[] bs2 = new Byte[bs.length];
		for (int i = 0; i < bs2.length; i++) {
			bs2[i] = bs[i];
		}
		return bs2;
	}
	public static <T>T to(Object obj,Class<T> type){
		if(obj == null){
			if(type==Integer.class){
				obj = 0;
			}else if(type==Long.class){
				obj = 0L;
			}else if(type==Short.class){
				obj = (short)0;
			}else if(type==Byte.class){
				obj = (byte)0;
			}else if(type==Float.class){
				obj = 0.0f;
			}else if(type==Double.class){
				obj = 0.0d;
			}else if(type==Character.class){
				obj = Character.valueOf((char)0);
			}else if(type==Boolean.class){
				obj = false;
			}
		}
		return (T) obj;
	}
	static char hexchar[] = "0123456789ABCDEF".toCharArray(); 
//	public static String toHexByBytes(byte[] bs){
//		StringBuilder hex = new StringBuilder(bs.length*2);
//		for (int i = 0; i < bs.length; i++) {
//			int b = bs[i]&255;
//			if(b<16){
//				hex.append(0);
//			}
//			hex.append(Integer.toHexString(b));
//		}
//		return hex.toString();
//	}
	public static String toHexByBytes(byte[] bs){
		char[] hex = new char[bs.length*2];
		for (int i = 0,j=0; i < bs.length; i++,j+=2) {
			byte b = bs[i];
			hex[j] = getHexCharByByte1(b);
			hex[j+1]=getHexCharByByte2(b);
		}
		return new String(hex);
	}
	
	public static char[] getHexChar2ByByte(byte b){
		char c1 = hexchar[(b>>4)&15];
		char c2 = hexchar[b&15];
		return new char[]{c1,c2};
	}
	public static char getHexCharByByte1(byte b){
		return hexchar[(b>>4)&15];
	}
	public static char getHexCharByByte2(byte b){
		return hexchar[b&15];
	}
	
//	public static byte[] toBytesByHex(String hex){
//		byte[] bs = new byte[hex.length()/2];
//		for (int i = 0; i < hex.length(); i+=2) {
//			bs[i/2] = ((Number)Integer.decode("0x"+hex.charAt(i)+hex.charAt(i+1))).byteValue();//Byte.decode("0x"+hex.charAt(i)+hex.charAt(i+1));
//		}
//		return bs;
//	}
	/** 十六进制转bytes 使用当前工具效率比较高
	 * 
	 * @param hex
	 * @return
	 */
	public static byte[] toBytesByHex(String hex){
		byte[] bs = new byte[hex.length()/2];
		for (int i = 0; i < hex.length(); i+=2) {
			bs[i/2] = getByteByHexChar2(hex.charAt(i),hex.charAt(i+1));//Byte.decode("0x"+hex.charAt(i)+hex.charAt(i+1));
		}
		return bs;
	}
	
	public static String toHost(int hostIp,boolean littleEnd){
		byte[] buf = toBytesByInt(hostIp, littleEnd);
		StringBuilder host = new StringBuilder(16);
		for (byte b : buf) {
			host.append(b&255).append('.');
		}
		return host.substring(0,host.length()-1);
	}
	public static int toIntByHost(String hostIp,boolean littleEnd){
		String[] vs = hostIp.split("\\.");
		byte[] bs = new byte[4];
		for (int i = 0; i < bs.length; i++) {
			bs[i] = (byte)Integer.parseInt(vs[i]);
		}
		return toIntByBytes(bs, littleEnd);
	}
	public static byte[] toBytesByHost(String hostIp){
		String[] vs = hostIp.split("\\.");
		byte[] bs = new byte[4];
		for (int i = 0; i < bs.length; i++) {
			bs[i] = (byte)Integer.parseInt(vs[i]);
		}
		return bs;
	}
	public static byte getByteByHexChar2(char hex1,char hex2){
		byte b1 = getByteByHexChar(hex1);
		byte b2 = getByteByHexChar(hex2);
		return (byte) ((b1 << 4)+b2);
	}
	public static byte getByteByHexChar(char hex){
		if(hex >= 97){
			return (byte) (hex - 87);
		}else if(hex >= 65){
			return (byte) (hex - 55);
		}else{
			return (byte) (hex - 48);
		}
	}
	public static Number toNumberByNumber(Number num,Class numType){
		Number result = num;
		if(isInt(numType)){
			result =  num.intValue();
		}else if(isLong(numType)){
			result =  num.longValue();
		}else if(isShort(numType)){
			result =  num.shortValue();
		}else if(isByte(numType)){
			result =  num.byteValue();
		}else if(isFloat(numType)){
			result = num.floatValue();
		}else if(isDouble(numType)){
			result = num.doubleValue();
		}else if(numType == BigDecimal.class){
			if(num instanceof BigDecimal){
				result = (BigDecimal)num;
			}else{
				result = new BigDecimal(num.doubleValue());
			}
		}
		return result;
	}
	public static void main(String[] args) {
		System.out.println(toHost(1145364856, true));
		System.out.println(Arrays.toString(toBytesByPrimitive(new Long[]{1l,2l}, true)));
		
		System.out.println(toStringByBytesBit1(toBytesByStringBit1("你看到我在干什么了吗", "utf-8"), "utf-8"));
		
		System.out.println(toPrimitiveByBytes(toBytesByPrimitive("1234567890", true),BigDecimal.class,true ,null));
		
		System.out.println(Arrays.toString(toShortersByBytes(toBytesByShorts(new short[]{1,2},false), false)));
		
		System.out.println(primitiveTypeSizeOf(new int[]{1,2,3}));
		//		Integer i = null;
//		System.out.println(to(null,Integer.class));
		
		System.out.println(toNumberByNumber(1, Integer.class).getClass());
		String hex = toHexByBytes(new byte[]{15,33,20,16,-1});
		System.out.println(hex);
		System.out.println(Arrays.toString(toBytesByHex (hex)));
		
		System.out.println(toHost(toIntByBytes(toBytesByHost("125.34.55.230"), true), true));
	}
	
	
	
	
	
	
	public static boolean isPrimitiveType(Class clazz){
		return clazz == int.class||clazz == Integer.class
				||clazz == long.class||clazz == Long.class
				||clazz == short.class||clazz == Short.class
				||clazz == byte.class||clazz == Byte.class
				||clazz == float.class||clazz == Float.class
				||clazz == double.class||clazz == Double.class
				||clazz == char.class||clazz == Character.class
				||clazz == boolean.class||clazz == Boolean.class
				;
	}
	
	public static boolean isPrimitiveArrays(Class clazz){
		return clazz == int[].class||clazz == Integer[].class
				||clazz == long[].class||clazz == Long[].class
				||clazz == short[].class||clazz == Short[].class
				||clazz == byte[].class||clazz == Byte[].class
				||clazz == float[].class||clazz == Float[].class
				||clazz == double[].class||clazz == Double[].class
				||clazz == char[].class||clazz == Character[].class
				||clazz == boolean[].class||clazz == Boolean[].class
				;
	}
	public static boolean isInt(Class clazz){
		return clazz == int.class||clazz == Integer.class;
	}
	public static boolean isLong(Class clazz){
		return clazz == long.class||clazz == Long.class;
	}
	public static boolean isShort(Class clazz){
		return clazz == short.class||clazz == Short.class;
	}
	public static boolean isByte(Class clazz){
		return clazz == byte.class||clazz == Byte.class;
	}
	public static boolean isFloat(Class clazz){
		return clazz == float.class||clazz == Float.class;
	}
	public static boolean isDouble(Class clazz){
		return clazz == double.class||clazz == Double.class;
	}
	public static boolean isChar(Class clazz){
		return clazz == char.class||clazz == Character.class;
	}
	public static boolean isBoolean(Class clazz){
		return clazz == boolean.class||clazz == Boolean.class;
	}
	public static boolean isStringex(Class clazz){
		return clazz == String.class||clazz == StringBuilder.class||clazz == StringBuffer.class;
	}
	public static String toStringByObject(Object obj){
		if(obj == null){
			return null;
		}
		return obj.toString();
	}
	public static <T>T getObjectOrDefault(T val,T def){
		if(val != null){
			return val;
		}
		return def;
	}
	
}
